package org.skipper.samples.spring.transaction.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.skipper.samples.spring.transaction.entity.UserInfo;
import org.skipper.samples.spring.transaction.mapper.UserInfoMapper;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * Created with IntelliJ IDEA.
 * Description:
 *
 * @author shoujian
 * Date: 2022-01-28
 * Time: 10:47 AM
 */
@Component
@Transactional
public class UserService {

    @Resource
    private UserInfoMapper userInfoMapper;

    @Transactional(isolation = Isolation.READ_UNCOMMITTED)
    public Boolean getUserInfoReadUncommitted(Long userId) throws InterruptedException {
        UserInfo userInfo = userInfoMapper.selectById(userId);

        //模拟业务运行
        Thread.sleep(3000L);
        UserInfo userInfo1 = userInfoMapper.selectById(userId);

        return userInfo1.getNickname().equals(userInfo.getNickname());
    }

    @Transactional(isolation = Isolation.READ_COMMITTED)
    public Boolean getUserInfoReadCommitted(Long userId) throws InterruptedException {
        UserInfo userInfo = userInfoMapper.selectById(userId);

        Thread.sleep(3000L);
        UserInfo userInfo1 = userInfoMapper.selectById(userId);

        return userInfo1.getNickname().equals(userInfo.getNickname());
    }

    @Transactional(isolation = Isolation.READ_COMMITTED)
    public Boolean getUserInfoRepeatableRead(String nickname) throws InterruptedException {
        int count = userInfoMapper.selectList(new QueryWrapper<UserInfo>().lambda().eq(UserInfo::getNickname, nickname)).size();

        Thread.sleep(3000L);
        int count1 = userInfoMapper.selectList(new QueryWrapper<UserInfo>().lambda().eq(UserInfo::getNickname, nickname)).size();
        return count != count1;
    }

    /**
     * 更新数据并睡眠3秒，抛错并回滚
     */
    @Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_UNCOMMITTED)
    public void updateSleepWithExceptionWithReadUncommitted(Long userId, String nickname) throws Exception {
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(userId);
        userInfo.setNickname(nickname);

        userInfoMapper.updateById(userInfo);

        throw new Exception("数据回滚");
    }

    /**
     * 更新数据并睡眠3秒，抛错并回滚
     */
    @Transactional(isolation = Isolation.READ_COMMITTED)
    public void updateWithReadCommitted(Long userId, String nickname) {
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(userId);
        userInfo.setNickname(nickname);

        userInfoMapper.updateById(userInfo);
    }

    @Transactional(isolation = Isolation.REPEATABLE_READ)
    public void deleteWithRepeatableRead(Long userId) {
        userInfoMapper.deleteById(userId);
    }

    @Transactional(isolation = Isolation.READ_COMMITTED)
    public void insert(UserInfo userInfo) {
        userInfoMapper.insert(userInfo);
    }

    public void update(Long userId1, String nickname1, Long userId2, String nickname2) throws InterruptedException {
        UserInfo userInfo1 = new UserInfo();
        userInfo1.setUserId(userId1);
        userInfo1.setNickname(nickname1);
        userInfoMapper.updateById(userInfo1);

        Thread.sleep(3000L);

        UserInfo userInfo2 = new UserInfo();
        userInfo2.setUserId(userId2);
        userInfo2.setNickname(nickname2);
        userInfoMapper.updateById(userInfo2);
    }



}
